/**********************************************************************************
***
***    Screencasting Teaching System C++ Library
***    Copyright (C) 2011  Jiri Novak <jiri.novak@petriny.net>
***                        Wadi Jalil Maluf <wadijm@gmail.com>
***
***    This file is part of the Screencasting Teaching System C++ Library.
***
***    This library is free software; you can redistribute it and/or modify
***    it under the terms of the GNU General Public License as published by
***   the Free Software Foundation; either version 3 of the License, or
***    (at your option) any later version.
***
***    This library is distributed in the hope that it will be useful,
***    but WITHOUT ANY WARRANTY; without even the implied warranty of
***    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
***   GNU General Public License for more details.
***
***    You should have received a copy of the GNU General Public License
***    along with this library; if not, write to the Free Software
***    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
***
*********************************************************************************/

#include "clientlistener.h"
#include "clientattender.h"
#include "../common/comm/socketmsgsender.h"
#include "../common/comm/blockingqueue.h"
#include "../common/comm/operation.h"
#include "../common/comm/sockettcp.h"
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <stdlib.h>



ClientListener::ClientListener(int port,std::string path)
{
  this->port = port;
  this->confPath=path;






}

ClientListener::~ClientListener()
{
  // TODO Auto-generated destructor stub
}

void ClientListener::close()
{
  // Primero hacemos joins y luego shutdown
  for (std::list<ClientAttender*>::iterator it = clients.begin(); it
      != clients.end(); it++)
    {
      ClientAttender* cliente = *it;
      cliente->freeResources();
      cliente->join();
    }
  for (std::list<ClientAttender*>::iterator it = clients.begin(); it
      != clients.end(); it++)
    {
      ClientAttender* cliente = *it;

      delete cliente;
      clients.erase(it++);
    }
  socket.closeSocket();
}

void ClientListener::checkResources()
{
  for (std::list<ClientAttender*>::iterator it = clients.begin(); it
      != clients.end(); it++)
    {
      ClientAttender* cliente = *it;
      if (cliente->isClosed())
        {

          cliente->join();
        }
    }
  for (std::list<ClientAttender*>::iterator it = clients.begin(); it
      != clients.end(); it++)
    {
      ClientAttender* cliente = *it;
      if (cliente->isClosed())
        {
          delete cliente;
          clients.erase(it++);
        }
    }

}

bool ClientListener::init()
{

  bool exito = socket.open();
  exito = exito && socket.bindTo(port);
  socket.listenTo(10);
  std::string pathUsersXml=this->confPath+"/users.xml";
  std::string pathCoursesXml=this->confPath+"/courses.xml";
  std::ifstream usersStream(pathUsersXml.c_str());
  std::ifstream coursesStream(pathCoursesXml.c_str());
  if(usersStream.good() && coursesStream.good()){
      service.loadData(coursesStream,usersStream);
  }else{
      exito=false;
  }
  return exito;
}



void ClientListener::run()
{
  while (socket.isAvaliable())
    {
      SocketTcp* s = socket.acceptSocket();
      checkResources();
      // Sino es null no hubo ningun problema al aceptar el socket
      if (s != NULL)
        {
          ClientAttender* thread = new ClientAttender(s,service,screencastService,confPath);
          thread->start();
          clients.push_back(thread);
        }
    }
}

bool ClientListener::isClosed() const
{
	return closed;
}

int ClientListener::getPort() const
{
    return port;
}
